#include "Shader.hpp"
#include <fstream>
#include <sstream>

Shader::Shader(std::string vertPath, std::string fragPath)
{
    std::ifstream vShaderFile, fShaderFile;

    vShaderFile.open(vertPath);
    fShaderFile.open(fragPath);
    
    if (vShaderFile.bad() || vShaderFile.fail() || fShaderFile.bad() || fShaderFile.fail())
    {
        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ\n"
                  << "----------------------------------------\n"
                  << "Can't open/read " + vertPath + " or " + fragPath;

        vShaderFile.close();
        fShaderFile.close();

        getchar();
        exit(EXIT_FAILURE);
    }

    std::string vertexCode, fragmentCode;
    std::stringstream vShaderStream, fShaderStream;

    vShaderStream << vShaderFile.rdbuf();
    fShaderStream << fShaderFile.rdbuf();

    vShaderFile.close();
    fShaderFile.close();

    vertexCode   = vShaderStream.str();
    fragmentCode = fShaderStream.str();

    const char* vShaderCode = vertexCode.c_str();
    const char* fShaderCode = fragmentCode.c_str();

    uint32_t vertex, fragment;
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, NULL);
    glCompileShader(vertex);
    checkCompileErrors(vertex, "VERTEX");

    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fShaderCode, NULL);
    glCompileShader(fragment);
    checkCompileErrors(fragment, "FRAGMENT");

    ID = glCreateProgram();
    glAttachShader(ID, vertex);
    glAttachShader(ID, fragment);
    glLinkProgram(ID);

    glDeleteShader(vertex);
    glDeleteShader(fragment);
}

void Shader::checkCompileErrors(uint32_t shader, std::string type)
{
    int success;
    char infoLog[1024];
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(shader, 1024, NULL, infoLog);
            std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n"
                      << infoLog <<"\n-- ----------------------------------------------- --\n";
        }
}
